<!doctype html>
<html>
  <head>
  	<style>
  		body {
  			font-family: sans-serif;
  			text-align: center;
  			background-color: lightgrey;
  		}

  		.logbox, .ubox, .msgbox {
  			border: 2px solid silver;
  		}
  		.logbox {
			margin-left: auto;
			margin-right: auto;
			background-color: lightblue;
			width: 350px;
			height: 50px;
			margin-top: 100px;
			padding: 20px;
  		}
  		.ubox {
  			background-color: lightcyan;
  			width: 120px;
  			height: 507px;
  			padding: 0;
  			font-size: .8em;
  		}
  		.msgbox {
  			background-color: beige;
			width: 500px;
			height: 500px;
			text-align: left;
			font-size: 0.8em;
			padding: 4px;
			overflow-y: scroll;
  		}
  		.infobox {
  			font-size: 0.8em;
  			margin-top: 60px;
  		}
  		#users {
		   list-style-type: square;
		   margin-left: 1em;
		   padding-left: 5px;
		   width: 100px;
		   text-align: left;
		   font-weight: bold;
		}
  	</style>
    <script src='http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js'></script>
    <script>
/*
-----------------------------------------------------
Chat protocol is very simple: 1 byte header + payload.
Header meanings :
   - u : new user enters the chat room
   - m : a user posted a message to the room
   - r : a user quits the room
-----------------------------------------------------
*/
    	var ws;
    	var user;
    	var msgbox;
    	var wsobj;

		function normalize(str) {return str.replace(/\s/g, '');}
    	function debug(str)		{ $("#debug").text(str); };

    	function info(str) {
    		$("#msg").append(str + '<br>');
    		msgbox.scrollTop = msgbox.scrollHeight;
    	}

		function ws_connect() {
			/* Initiate the connection to the server using a web socket */
			ws = new wsobj("ws://" + location.host + "/chat.rsp");

			ws.onopen = function() {
				debug("online");
				user = $("[name=login]").val();
				ws.send('u' + user);			/* Send the user name to the server */
				$("#post").focus();
			};

			ws.onmessage = function(evt) {
				var msg = evt.data.slice(1); 	/* Extract the payload bypassing the header */

				switch(evt.data[0]) {		 	/* 1 byte header action value */
					case 'u':
						$("#users").append('<li id="_' + normalize(msg) + '">' + msg + '</li>');
						info('<font color="darkgreen">' + msg + ' enters...</font>');
						break;
					case 'm':
						info(msg);
						break;
					case 'r':
						$("#_" + normalize(msg)).remove();
						info('<font color="darkred">' + msg + ' exits...</font>');
						break;
				};
			};

			ws.onclose = function() {debug("offline");};
		}

		function enter_chat() {
			if (jQuery.trim($("[name=login]").val()) != '') {
				ws_connect();
				$("#login").hide();
				$(".hideable").show();
			}
		}

		function post_msg() {
			if ($("#post").val() != '') {
				ws.send('m' + user + ': ' + $("#post").val());
				$("#post").val('');
			}
			$("#post").focus();
		}

		$(document).ready(
			function(){
				$(".hideable").hide();

				wsobj = window.WebSocket;			/* W3C */
				if (wsobj === undefined) {
					wsobj = window.MozWebSocket;	/* Firefox */
					if (wsobj === undefined)
						alert("Your browser doesn't support Web Sockets!");
				}

				$("#enter").click(          function(event) {enter_chat();});
				$("[name=send]").click(     function(event) {post_msg();});

				$("[name=login]").keypress( function(event) {if (event.which == 13 ) enter_chat();});
				$("#post").keypress(        function(event) {if (event.which == 13 ) post_msg();});

				msgbox = document.getElementById("msg");
				$("[name=login]").focus();
			}
		);
    </script>
  </head>
  <body>
		<h2>Realtime chat demo using websockets</h2>
		<small>- <i>requires a websocket <a href="http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-10" target="_new">hybi-10</a> enabled browser like Chrome 14, FF 8 or IE 10</i> -</small>
		<br><br>
		<div class="hideable">Connection state : <span id="debug">connecting...</span></div>

		<div id="login" class="logbox" align="center">
			<b>User name</b>
			<input type="text" name="login">
			<button id="enter">Connect</button>
		</div>

		<table align="center" style="margin-top:20px">
			<tr>
				<td>
					<div id="list" class="ubox hideable">
						<ul id="users"></ul>
					</div>
				</td><td>
					<div id="msg" class="msgbox hideable"></div>
				</td>
			</tr><tr>
				<td colspan="2" align="right" style="padding-right:20px">
					<input type="text" name="post" id="post" size="68" class="hideable">
					<button name="send" class="hideable">Send</button>
				<td>
			</tr>
		</table>

		<div class="infobox">
			This demo is powered by the <a href="http://cheyenne-server.org">Cheyenne Web Server</a> using the latest revision from our
			<a href="http://code.google.com/p/cheyenne-server/source/checkout">SVN repository</a>.
			<br>
			You can find the server-side source code of this demo <a href="http://code.google.com/p/cheyenne-server/source/browse/trunk/Cheyenne/www/ws-apps/chat.r">here</a>.
			<br><br>
			More informations and contact info in <a href="http://cheyenne-server.org/blog.rsp">Cheyenne's blog</a>.
		</div>
  </body>
</html>